import React, { useEffect, useState } from 'react';
import type { ReactNode } from 'react';
import { Pagination } from 'antd';
import { LoadingOutlined } from '@ant-design/icons';
import SeeMoreBtn from '../SyncComponents/SeeMoreBtn';
import type { SeeMoreBtnProps } from '../SyncComponents/SeeMoreBtn';
import './index.less';

interface ILoadParams {
  pageNo: number;
  pageSize: number;
}

interface IDataRes {
  result: number;
  data: any[];
  total: number;
}

interface IState {
  pageNo: number;
  total: number;
  loading: boolean;
  data: any[];
  ready: boolean;
  setData: (data: any[]) => void;
  setLoading: (loading: boolean) => void;
  setTotal: (total: number) => void;
  setPageNo: (pageNo: number) => void;
  setPageSize: (pageSize: number) => void;
}

interface IProps {
  renderRow: (row: any, index: number) => ReactNode;
  renderLoading?: (loading: boolean) => ReactNode;
  renderPagination?: (
    pageNo: number,
    pageSize: number,
    total: number,
  ) => ReactNode;
  renderBefore?: (params: IProps & IState) => ReactNode;
  renderAfter?: (params: IProps & IState) => ReactNode;
  renderEmpty?: (params: IProps & IState) => ReactNode;
  onLoad: (params: ILoadParams, allState: IProps & IState) => Promise<IDataRes>;
  onPagination: (
    params: ILoadParams,
    allState: IProps & IState,
  ) => Promise<IDataRes>;
  pageSize: number;
  className: string;
  contentClassName?: string;
  style: Record<string, any>;
  hidePagination: boolean;
  dataLoadMode: 'pagination' | 'more';
  seeMoreBtnProps: SeeMoreBtnProps;
}

function SimpleList(props: IProps) {
  const {
    renderRow,
    renderLoading,
    renderPagination,
    renderBefore,
    renderAfter,
    renderEmpty,
    pageSize: props_pageSize = 10,
    onLoad,
    style,
    className,
    onPagination,
    dataLoadMode,
    hidePagination,
    seeMoreBtnProps,
    contentClassName,
  } = props;
  const [ready, setReady] = useState(false);
  const [loading, setLoading] = useState(false);
  const [pageNo, setPageNo] = useState(1);
  const [pageSize, setPageSize] = useState(props_pageSize);
  const [total, setTotal] = useState(0);
  const [data, setData] = useState([]);

  const allState: IProps & IState = {
    ...props,
    ready,
    pageNo,
    total,
    loading,
    data,
    setData,
    setLoading,
    setTotal,
    setPageNo,
    setPageSize,
  };

  useEffect(() => {
    setLoading(true);
    const params = {
      pageNo: 1,
    };
    onLoad(
      {
        pageNo: params.pageNo,
        pageSize,
      },
      allState,
    )
      .then((res) => {
        if (res?.result == 0) {
          setData(res.data);
          setPageNo(params.pageNo);
          setTotal(res.total);
        }
        return res;
      })
      .finally(() => {
        setLoading(false);
        setReady(true);
      });
  }, []);

  const onPaginationChange = (pageNo: number, pageSize: number) => {
    setLoading(true);
    const params = {
      pageNo,
      pageSize,
    };
    onPagination(params, allState)
      .then((res) => {
        if (res?.result == 0) {
          setData(res.data);
          setPageNo(params.pageNo);
          setTotal(res.total);
        }
        return res;
      })
      .finally(() => {
        setLoading(false);
      });
  };

  return (
    <div style={style} className={`simpleList ${className}`}>
      {renderBefore ? renderBefore(allState) : null}
      <div className={`simpleList-content ${contentClassName}`}>
        {ready && !data.length
          ? renderEmpty
            ? renderEmpty(allState)
            : null
          : data.map(renderRow)}
        {renderLoading ? (
          renderLoading(loading)
        ) : loading ? (
          <div className="simpleList-loading">
            <LoadingOutlined />
          </div>
        ) : null}
      </div>
      {renderAfter ? renderAfter(allState) : null}
      {renderPagination ? (
        renderPagination(pageNo, pageSize, total)
      ) : hidePagination ? null : (
        <div className="alignRight">
          {dataLoadMode == 'pagination' ? (
            <Pagination
              onChange={onPaginationChange}
              simple
              defaultCurrent={1}
              current={pageNo}
              total={total}
              pageSize={pageSize}
            />
          ) : (
            <SeeMoreBtn {...seeMoreBtnProps} />
          )}
        </div>
      )}
    </div>
  );
}

export default SimpleList;
